
#include "studio_mqtt_client.h"
#include "log/studio_log.h"

#include "system/studio_uuid.h"
#if ENABLE_PAHO_MQTT
#include <mqtt/client.h>
#include <mqtt/ssl_options.h>
#include <mqtt/async_client.h>

#endif

const auto PERIOD = std::chrono::seconds(20);
const auto TIMEOUT = std::chrono::seconds(10);
const int MAX_BUFFERED_MSGS = 120;  // 120 * 5sec => 10min off-line buffering

bool studio_mqtt_client::publish(const std::string& topic, const std::string& payload)
{
    bool status = false;
    // 创建 MQTT 异步客户端
    std::string uri = m_protocol + "://" + m_host + ":" + std::to_string(m_port);

    mqtt::async_client client(uri, m_client_id);

    // 配置连接选项
    mqtt::connect_options connOpts;
    connOpts.set_clean_session(true);
    connOpts.set_user_name(m_user);
    connOpts.set_password(m_password);

    try
    {
        // 创建连接完成的回调对象
        pub_callback cb;
        // 设置异步客户端的回调
        client.set_callback(cb);

        // 连接到 MQTT Broker
        std::cout << "Connecting to server: " << uri << std::endl;
        mqtt::token_ptr conntok = client.connect(connOpts);
        conntok->wait();  // 等待连接完成// 使用异步连接，等待连接完成

        std::cout << "Connection successful!" << std::endl;
        int index = 1;
        while (true)
        {
            // 构造消息内容
            std::string message = "Hello, MQTT! " + std::to_string(index++);
            mqtt::message_ptr pubmsg = mqtt::make_message("test/car", message);
            pubmsg->set_qos(1);

            // 发布消息
            client.publish(pubmsg)->wait_for(TIMEOUT);
            // 等待 1 秒
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }

        // 断开连接
        client.disconnect()->wait();  // 使用异步断开，等待断开完成
        std::cout << "Disconnected." << std::endl;
    }
    catch (const mqtt::exception& exc)
    {
        std::cerr << "\nError: " << exc.what() << std::endl;
        return 1;
    }

    status = true;
    return status;
}

bool studio_mqtt_client::subscribe()
{
    bool status = false;
    // 创建 MQTT 异步客户端
    std::string uri = m_protocol + "://" + m_host + ":" + std::to_string(m_port);

    // mqtt::async_client client(uri, m_topic_name, PERSIST_DIR);
    mqtt::async_client cli(uri, m_client_id);

    mqtt::connect_options connOpts;
    connOpts.set_clean_session(true);  // 启用非干净会话，服务器会记住客户端的消息状态
    connOpts.set_user_name(m_user);
    connOpts.set_password(m_password);

    subs_callback cb(cli, connOpts, m_topic_name, m_client_id);
    cli.set_callback(cb);

    try
    {
        std::cout << "Connecting to the MQTT server '" << uri << "'..." << std::flush;
        cli.connect(connOpts, nullptr, cb);
    }
    catch (const mqtt::exception& exc)
    {
        std::cerr << "\nERROR: Unable to connect to MQTT server: '" << uri << "'" << exc << std::endl;
        return 1;
    }

    return false;
}

bool studio_mqtt_client::check()
{
    return false;
}

void studio_mqtt_client::client_id(const std::string& ci)
{
    m_client_id = ci;
}

void studio_mqtt_client::user(const std::string& u)
{
    m_user = u;
}

void studio_mqtt_client::password(const std::string& p)
{
    m_password = p;
}

void studio_mqtt_client::host(const std::string& h)
{
    m_host = h;
}

void studio_mqtt_client::port(const int& p)
{
    m_port = p;
}

void studio_mqtt_client::qos(const int& q)
{
    m_qos = q;
}

void studio_mqtt_client::protocol(const std::string& p)
{
    m_protocol = p;
}

void studio_mqtt_client::topic_name(const std::string& t)
{
    m_topic_name = t;
}

// void studio_mqtt_client::server(const std::string& s)
//{
//     m_server = s;
// }

void studio_mqtt_client::server(const std::string& s)
{
    auto pos = s.find("://");
    if (pos != std::string::npos)
    {
        protocol(s.substr(0, pos));
    }
    std::string ss = s.substr(pos + 3);
    pos = ss.find(":");
    if (pos != std::string::npos)
    {
        port(std::stoi(ss.substr(pos + 1)));
        ss = ss.substr(0, pos);
    }
    host(ss);
}
